package com.prp.bo;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;

import org.hibernate.Transaction;

import com.prp.db.DAOFactory;
import com.prp.db.HibernateSessionFactory;
import com.prp.db.idao.IMailDAO;
import com.prp.db.idao.IMailboxDAO;
import com.prp.db.po.Mail;
import com.prp.db.po.Mailbox;

public class MailBO{
	
	/**
	 * 生成一个Mail对象，并写入数据库
	 * @param mailId
	 * @param title
	 * @param content
	 * @return null if commit error
	 */
	public synchronized static Mail addMail(String content) {
		Date date = new Date();
		Mail mail = null;
		DAOFactory factory = DAOFactory.getDAOFactory();
		IMailDAO mDao = factory.getMailDAO();
		Transaction tx = null;
		try {
			tx = HibernateSessionFactory.getSession().beginTransaction();
			mail = new Mail(content, date);
			mDao.save(mail);
			tx.commit();
		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
			return null;
		} finally {
			HibernateSessionFactory.getSession().close();
		}
		return mail;
	}
	
	/**
	 * 将Mail发送，并且可以选择是否保存在自己的发件箱
	 * @param senderId
	 * @param receiveId
	 * @param mailId
	 * @param saveInOutbox
	 * @return -1 send error mail not found, 0 commit error, 1 commit OK
	 */
	public synchronized static Mailbox sendMail(int senderId, int receiverId, int mailId, String title, boolean saveInOutbox) {
		Mailbox mailbox = null;
		DAOFactory factory = DAOFactory.getDAOFactory();
		IMailboxDAO mbDao = factory.getMailboxDAO();
		IMailDAO mDao = factory.getMailDAO();
		Transaction tx = null;
		try {
			tx = HibernateSessionFactory.getSession().beginTransaction();
			if (mDao.findById(mailId) == null) {
				HibernateSessionFactory.getSession().close();
				return null;
			}
			if (saveInOutbox) {
				mailbox = new Mailbox(mailId, senderId, receiverId, SNSConstants.MAIL_STATE_UNREAD_EXIST_ALL, title);
			} else {
				mailbox = new Mailbox(mailId, senderId, receiverId, SNSConstants.MAIL_STATE_UNREAD_EXIST_RECEIVE, title);
			}
			mbDao.save(mailbox);
			tx.commit();
		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
			return null;
		} finally {
			HibernateSessionFactory.getSession().close();
		}
		return mailbox;
	}
	
	/**
	 * 将一个Mail标记为已读
	 * @param senderId
	 * @param receiveId
	 * @param mailId
	 * @param id
	 * @return -2 mail not right, -1 mail not found, 0 commit error, 1 commit OK
	 */
	public synchronized static int readMail(int senderId, int receiverId, int mailId, int id) {
		DAOFactory factory = DAOFactory.getDAOFactory();
		IMailboxDAO mbDao = factory.getMailboxDAO();
		Transaction tx = null;
		try {
			tx = HibernateSessionFactory.getSession().beginTransaction();
			if (mbDao.findById(id) == null) {
				HibernateSessionFactory.getSession().close();
				return -1;
			}
			Mailbox mailbox = mbDao.findById(id);
//			if (mailbox.getSenderId() != senderId || mailbox.getReceiverId() != receiverId || mailbox.getMailId() != mailId) {
//				HibernateSessionFactory.getSession().close();
//				return -2;
//			}
			switch (mailbox.getState()) {
				case SNSConstants.MAIL_STATE_UNREAD_EXIST_ALL:
					mailbox.setState(SNSConstants.MAIL_STATE_READ_EXIST_ALL);
					mbDao.attachDirty(mailbox);
					break;
				case SNSConstants.MAIL_STATE_UNREAD_EXIST_RECEIVE:
					mailbox.setState(SNSConstants.MAIL_STATE_READ_EXIST_RECEIVE);
					mbDao.attachDirty(mailbox);
					break;
				default:
					break;
			}
			tx.commit();
		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
			return 0;
		} finally {
			HibernateSessionFactory.getSession().close();
		}
		return 1;
	}
	
	/**
	 * 从收件箱中删除邮件
	 * @param senderId
	 * @param receiveId
	 * @param mailId
	 * @param id
	 * @return -3 mail already deleted, -2 mail not right, -1 mail not found, 0 commit error, 1 commit OK
	 */
	public synchronized static int deleteInInbox (int senderId, int receiverId, int mailId, int id) {
		
		DAOFactory factory = DAOFactory.getDAOFactory();
		IMailboxDAO mbDao = factory.getMailboxDAO();
		IMailDAO mDao = factory.getMailDAO();
		Transaction tx = null;
		try {
			tx = HibernateSessionFactory.getSession().beginTransaction();
			if (mbDao.findById(id) == null) {
				HibernateSessionFactory.getSession().close();
				return -1;
			}
			Mailbox mailbox = mbDao.findById(id);
//			if (mailbox.getSenderId() != senderId || mailbox.getReceiverId() != receiverId || mailbox.getMailId() != mailId) {
//				HibernateSessionFactory.getSession().close();
//				return -2;
//			}
			switch (mailbox.getState()) {
				case SNSConstants.MAIL_STATE_READ_EXIST_ALL:
					mailbox.setState(SNSConstants.MAIL_STATE_READ_EXIST_SEND);
					mbDao.attachDirty(mailbox);
					break;
				case SNSConstants.MAIL_STATE_READ_EXIST_RECEIVE:
					mbDao.delete(mailbox);
					if (mbDao.findByMailId(mailId) == null)
						mDao.delete(mDao.findById(mailId));
					else if (mbDao.findByMailId(mailId).size() == 0)
						mDao.delete(mDao.findById(mailId));
					break;
				case SNSConstants.MAIL_STATE_READ_EXIST_SEND:
					HibernateSessionFactory.getSession().close();
					return -3;
				case SNSConstants.MAIL_STATE_UNREAD_EXIST_ALL:
					mailbox.setState(SNSConstants.MAIL_STATE_UNREAD_EXIST_SEND);
					mbDao.attachDirty(mailbox);
					break;
				case SNSConstants.MAIL_STATE_UNREAD_EXIST_RECEIVE:
					mbDao.delete(mailbox);
					if (mbDao.findByMailId(mailId) == null)
						mDao.delete(mDao.findById(mailId));
					else if (mbDao.findByMailId(mailId).size() == 0)
						mDao.delete(mDao.findById(mailId));
					break;
				case SNSConstants.MAIL_STATE_UNREAD_EXIST_SEND:
					HibernateSessionFactory.getSession().close();
					return -3;
				default:
					break;
			}
			tx.commit();
		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
			return 0;
		} finally {
			HibernateSessionFactory.getSession().close();
		}
		return 1;
	}
	
	/**
	 * 从发件箱中删除邮件
	 * @param senderId
	 * @param receiveId
	 * @param mailId
	 * @param id
	 * @return -3 mail already deleted, -2 mail not right, -1 mail not found, 0 commit error, 1 commit OK
	 */
	public synchronized static int deleteInOutbox (int senderId, int receiverId, int mailId, int id) {
		
		DAOFactory factory = DAOFactory.getDAOFactory();
		IMailboxDAO mbDao = factory.getMailboxDAO();
		IMailDAO mDao = factory.getMailDAO();
		Transaction tx = null;
		try {
			tx = HibernateSessionFactory.getSession().beginTransaction();
			if (mbDao.findById(id) == null) {
				HibernateSessionFactory.getSession().close();
				return -1;
			}
			Mailbox mailbox = mbDao.findById(id);
//			if (mailbox.getSenderId() != senderId || mailbox.getReceiverId() != receiverId || mailbox.getMailId() != mailId) {
//				HibernateSessionFactory.getSession().close();
//				return -2;
//			}
			switch (mailbox.getState()) {
				case SNSConstants.MAIL_STATE_READ_EXIST_ALL:
					mailbox.setState(SNSConstants.MAIL_STATE_READ_EXIST_RECEIVE);
					mbDao.attachDirty(mailbox);
					break;
				case SNSConstants.MAIL_STATE_READ_EXIST_RECEIVE:
					HibernateSessionFactory.getSession().close();
					return -3;
				case SNSConstants.MAIL_STATE_READ_EXIST_SEND:
					mbDao.delete(mailbox);
					if (mbDao.findByMailId(mailId) == null)
						mDao.delete(mDao.findById(mailId));
					else if (mbDao.findByMailId(mailId).size() == 0)
						mDao.delete(mDao.findById(mailId));
					break;
				case SNSConstants.MAIL_STATE_UNREAD_EXIST_ALL:
					mailbox.setState(SNSConstants.MAIL_STATE_UNREAD_EXIST_RECEIVE);
					mbDao.attachDirty(mailbox);
					break;
				case SNSConstants.MAIL_STATE_UNREAD_EXIST_RECEIVE:
					HibernateSessionFactory.getSession().close();
					return -3;
				case SNSConstants.MAIL_STATE_UNREAD_EXIST_SEND:
					mbDao.delete(mailbox);
					if (mbDao.findByMailId(mailId) == null)
						mDao.delete(mDao.findById(mailId));
					else if (mbDao.findByMailId(mailId).size() == 0)
						mDao.delete(mDao.findById(mailId));
					break;
				default:
					break;
			}
			tx.commit();
		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
			return 0;
		} finally {
			HibernateSessionFactory.getSession().close();
		}
		return 1;
	}
	
	/**
	 * 获取特定的一份邮件内容
	 * @param mailId
	 * @return null if the Mail is not exist
	 */
	public synchronized static Mail getMail (int mailId) {
		DAOFactory factory = DAOFactory.getDAOFactory();
		IMailDAO mDao = factory.getMailDAO();
		Mail mail = null;
		Transaction tx = null;
		try {
			tx = HibernateSessionFactory.getSession().beginTransaction();
			mail = mDao.findById(mailId);
			tx.commit();
		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
			return mail;
		} finally {
			HibernateSessionFactory.getSession().close();
		}
		return mail;
	}
	
	/**
	 * 从收件箱中获取特定两个人的通信记录
	 * @param senderId
	 * @param receiveId
	 * @return null if the Mail is not exist
	 */
	public synchronized static ArrayList<Mailbox> getInboxMailList (int senderId, int receiverId) {
		DAOFactory factory = DAOFactory.getDAOFactory();
		IMailboxDAO mbDao = factory.getMailboxDAO();
		ArrayList<Mailbox> result = new ArrayList<Mailbox>();
		Transaction tx = null;
		try {
			tx = HibernateSessionFactory.getSession().beginTransaction();
			ArrayList<Mailbox> temp = (ArrayList<Mailbox>) mbDao.findBySenderReceiver(senderId, receiverId);
			for (Iterator<Mailbox> it = temp.iterator(); it.hasNext();) {
				Mailbox tempbox = it.next();
				switch (tempbox.getState()) {
					case SNSConstants.MAIL_STATE_READ_EXIST_ALL:
						result.add(tempbox);
						continue;
					case SNSConstants.MAIL_STATE_READ_EXIST_RECEIVE:
						result.add(tempbox);
						continue;
					case SNSConstants.MAIL_STATE_UNREAD_EXIST_ALL:
						result.add(tempbox);
						continue;
					case SNSConstants.MAIL_STATE_UNREAD_EXIST_RECEIVE:
						result.add(tempbox);
						continue;
					default:
						continue;
				}
			}
			tx.commit();
		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
			return result;
		} finally {
			HibernateSessionFactory.getSession().close();
		}
		return result;
	}
	
	/**
	 * 从收件箱中获取一个人的所有通信记录
	 * @param receiveId
	 * @return null if the Mail is not exist
	 */
	public synchronized static ArrayList<Mailbox> getInboxMailList (int receiverId) {
		DAOFactory factory = DAOFactory.getDAOFactory();
		IMailboxDAO mbDao = factory.getMailboxDAO();
		ArrayList<Mailbox> result = new ArrayList<Mailbox>();
		Transaction tx = null;
		try {
			tx = HibernateSessionFactory.getSession().beginTransaction();
			ArrayList<Mailbox> temp = (ArrayList<Mailbox>) mbDao.findByReceiverId(receiverId);
			for (Iterator<Mailbox> it = temp.iterator(); it.hasNext();) {
				Mailbox tempbox = it.next();
				switch (tempbox.getState()) {
					case SNSConstants.MAIL_STATE_READ_EXIST_ALL:
						result.add(tempbox);
						continue;
					case SNSConstants.MAIL_STATE_READ_EXIST_RECEIVE:
						result.add(tempbox);
						continue;
					case SNSConstants.MAIL_STATE_UNREAD_EXIST_ALL:
						result.add(tempbox);
						continue;
					case SNSConstants.MAIL_STATE_UNREAD_EXIST_RECEIVE:
						result.add(tempbox);
						continue;
					default:
						continue;
				}
			}
			tx.commit();
		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
			return result;
		} finally {
			HibernateSessionFactory.getSession().close();
		}
		return result;
	}
	
	/**
	 * 获取收件箱中的指定邮件。
	 * @param mailboxId
	 * @return null if error
	 */
	public synchronized static Mailbox getInboxMail (int mailboxId) {
		DAOFactory factory = DAOFactory.getDAOFactory();
		IMailboxDAO mbDao = factory.getMailboxDAO();
		Mailbox mailbox = null;
		Transaction tx = null;
		try {
			tx = HibernateSessionFactory.getSession().beginTransaction();
			mailbox = mbDao.findById(mailboxId);
			if (mailbox == null) {
				HibernateSessionFactory.getSession().close();
				return null;
			}
			tx.commit();
		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
			return null;
		} finally {
			HibernateSessionFactory.getSession().close();
		}
		switch (mailbox.getState()) {
			case SNSConstants.MAIL_STATE_READ_EXIST_SEND:
				return null;
			case SNSConstants.MAIL_STATE_UNREAD_EXIST_SEND:
				return null;
			default:
				break;
		}
		return mailbox;
	}
	
	/**
	 * 从发件想中获取特定两个人的通信记录
	 * @param senderId
	 * @param receiveId
	 * @return null if the Mail is not exist
	 */
	public synchronized static ArrayList<Mailbox> getOutboxMailList (int senderId, int receiverId) {
		DAOFactory factory = DAOFactory.getDAOFactory();
		IMailboxDAO mbDao = factory.getMailboxDAO();
		ArrayList<Mailbox> result = new ArrayList<Mailbox>();
		Transaction tx = null;
		try {
			tx = HibernateSessionFactory.getSession().beginTransaction();
			ArrayList<Mailbox> temp = (ArrayList<Mailbox>) mbDao.findBySenderReceiver(senderId, receiverId);
			for (Iterator<Mailbox> it = temp.iterator(); it.hasNext();) {
				Mailbox tempbox = it.next();
				switch (tempbox.getState()) {
					case SNSConstants.MAIL_STATE_READ_EXIST_ALL:
						result.add(tempbox);
						continue;
					case SNSConstants.MAIL_STATE_READ_EXIST_SEND:
						result.add(tempbox);
						continue;
					case SNSConstants.MAIL_STATE_UNREAD_EXIST_ALL:
						result.add(tempbox);
						continue;
					case SNSConstants.MAIL_STATE_UNREAD_EXIST_SEND:
						result.add(tempbox);
						continue;
					default:
						continue;
				}
			}
			tx.commit();
		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
			return result;
		} finally {
			HibernateSessionFactory.getSession().close();
		}
		return result;
	}
	
	/**
	 * 从发件箱中获取一个人的所有通信记录
	 * @param senderId
	 * @return null if the Mail is not exist
	 */
	public synchronized static ArrayList<Mailbox> getOutboxMailList (int senderId) {
		DAOFactory factory = DAOFactory.getDAOFactory();
		IMailboxDAO mbDao = factory.getMailboxDAO();
		ArrayList<Mailbox> result = new ArrayList<Mailbox>();
		Transaction tx = null;
		try {
			tx = HibernateSessionFactory.getSession().beginTransaction();
			ArrayList<Mailbox> temp = (ArrayList<Mailbox>) mbDao.findBySenderId(senderId);
			for (Iterator<Mailbox> it = temp.iterator(); it.hasNext();) {
				Mailbox tempbox = it.next();
				switch (tempbox.getState()) {
					case SNSConstants.MAIL_STATE_READ_EXIST_ALL:
						result.add(tempbox);
						continue;
					case SNSConstants.MAIL_STATE_READ_EXIST_SEND:
						result.add(tempbox);
						continue;
					case SNSConstants.MAIL_STATE_UNREAD_EXIST_ALL:
						result.add(tempbox);
						continue;
					case SNSConstants.MAIL_STATE_UNREAD_EXIST_SEND:
						result.add(tempbox);
						continue;
					default:
						continue;
				}
			}
			tx.commit();
		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
			return result;
		} finally {
			HibernateSessionFactory.getSession().close();
		}
		return result;
	}
	
	/**
	 * 获取发件箱中的指定邮件。
	 * @param mailboxId
	 * @return null if error
	 */
	public synchronized static Mailbox getOutboxMail (int mailboxId) {
		DAOFactory factory = DAOFactory.getDAOFactory();
		IMailboxDAO mbDao = factory.getMailboxDAO();
		Mailbox mailbox = null;
		Transaction tx = null;
		try {
			tx = HibernateSessionFactory.getSession().beginTransaction();
			mailbox = mbDao.findById(mailboxId);
			if (mailbox == null) {
				HibernateSessionFactory.getSession().close();
				return null;
			}
			tx.commit();
		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
			return null;
		} finally {
			HibernateSessionFactory.getSession().close();
		}
		switch (mailbox.getState()) {
			case SNSConstants.MAIL_STATE_READ_EXIST_RECEIVE:
				return null;
			case SNSConstants.MAIL_STATE_UNREAD_EXIST_RECEIVE:
				return null;
			default:
				break;
		}
		return mailbox;
	}
	
	/**
	 * 获取指定邮件。
	 * @param mailboxId
	 * @return null if error
	 */
	public synchronized static Mailbox getMailbox (int mailboxId) {
		DAOFactory factory = DAOFactory.getDAOFactory();
		IMailboxDAO mbDao = factory.getMailboxDAO();
		Mailbox mailbox = null;
		Transaction tx = null;
		try {
			tx = HibernateSessionFactory.getSession().beginTransaction();
			mailbox = mbDao.findById(mailboxId);
			if (mailbox == null) {
				HibernateSessionFactory.getSession().close();
				return null;
			}
			tx.commit();
		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
			return null;
		} finally {
			HibernateSessionFactory.getSession().close();
		}
		return mailbox;
	}

}
